package com.lmc.gobang.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lmc.gobang.game.MatchRequest;
import com.lmc.gobang.game.MatchResponse;
import com.lmc.gobang.game.Matcher;
import com.lmc.gobang.game.OnlineUserManager;
import com.lmc.gobang.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

@Slf4j
@Component
public class MatchAPI extends TextWebSocketHandler {

    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("Connected to websocket");
        try {
            User user  = (User) session.getAttributes().get("user");
            //防止浏览器多开
            //判断已上线用户的session是否为空，不为空说明已登录
            if(onlineUserManager.getFromGameHall(user.getUserId()) != null
                    || onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
                log.info("玩家"+user.getUsername()+"尝试多开");
                onlineUserManager.printGameHall();
                onlineUserManager.printGameRoom();
                MatchResponse response = new MatchResponse();
                response.setOk(true);
                response.setReason("您已在其它客户端登录，请勿重复登录!");
                response.setMessage("RepeatConnection");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                //强迫下线
//                session.close();
                return;
            }
            WebSocketSession existingSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (existingSession != null && !existingSession.equals(session)) {
                // 如果已经有其他连接，强制关闭旧连接
                try {
                    existingSession.close();
                } catch (IOException e) {
                    log.error("关闭旧连接失败", e);
                }
            }
                onlineUserManager.enterGameHall(user.getUserId(), session);
                log.info("玩家"+user.getUsername()+"进入游戏大厅");

        } catch (NullPointerException e) {
            log.info("当前用户未登录");
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("您尚未登录！请先登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        log.info("Received text message");
        //获取用户信息
        User user  = (User) session.getAttributes().get("user");
        //获取客户端发来的数据
        String payload = message.getPayload();
        //请求载荷是一个JSON格式，需要将其转换成JAVA对象
        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
        //处理请求
        MatchResponse response = new MatchResponse();
        if("startMatch".equals(request.getMessage())){
            //进入匹配队列
            //先创建一个匹配队列，把当前用户加进去
            matcher.add(user);
            //加入完成后发送响应
            response.setOk(true);
            response.setMessage("startMatch");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
//            log.info("玩家"+user.getUsername()+"已进入匹配队列");
        } else if ("stopMatch".equals(request.getMessage())) {
            //退出匹配队列
            //先创建一个匹配队列，把当前用户从队列中移除出去
            matcher.remore(user);
            //移除完成后发送响应
            response.setOk(true);
            response.setMessage("stopMatch");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            log.info("玩家"+user.getUsername()+"已退出匹配队列");
        }else{
            //异常请求
            response.setOk(false);
            response.setReason("非法的匹配请求");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            log.info("玩家"+user.getUsername()+"发送非法请求");
        }

    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            //玩家下线，从onlineUserManager中删除
            User user  = (User) session.getAttributes().get("user");
            //防止在对多开玩家下线操作时使原玩家下线(因为他们的userid是相同的)需要对session进行判断
            WebSocketSession tmpsession = onlineUserManager.getFromGameHall(user.getUserId());
            if(tmpsession == session ) {
                onlineUserManager.exitGameHall(user.getUserId());
                onlineUserManager.printGameHall();
                log.info("[handleTransportError]玩家"+user.getUsername()+"离开游戏大厅");
                //如果玩家还在匹配队列中却断开连接
            }
            matcher.remore(user);

//            else{
//                matcher.remore(user);
//                log.info("玩家"+user.getUsername()+"多开，已使其下线离开游戏大厅");
//            }

        } catch (NullPointerException e) {
            log.info("当前用户未登录");
//            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录！请先登录");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            //玩家下线，从onlineUserManager中删除
            User user  = (User) session.getAttributes().get("user");
            //防止在对多开玩家下线操作时使原玩家下线(因为他们的userid是相同的)需要对session进行判断
            WebSocketSession tmpsession = onlineUserManager.getFromGameHall(user.getUserId());
            if(tmpsession == session ) {
                onlineUserManager.exitGameHall(user.getUserId());
                onlineUserManager.printGameHall();
                log.info("[afterConnectionClosed]玩家"+user.getUsername()+"离开游戏大厅");
                //如果玩家还在匹配队列中却断开连接
            }
            matcher.remore(user);

//            else{
//                matcher.remore(user);
//                log.info("玩家"+user.getUsername()+"多开，已使其下线离开游戏大厅");
//            }

        } catch (NullPointerException e) {
            log.info("当前用户未登录");
//            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录！请先登录");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }
}
